﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Collections;
using ICSharpCode.SharpZipLib.Zip;

namespace Generator.Helpers
{
    /// <summary>
    /// Cette classe permet de faire un Zip d'un répertoire
    /// </summary>
    internal class ZipHelper
    {
        #region ZipFolder Method

        /// <summary>
        /// Cette méthode permet de faire un Zip d'un répertoire
        /// </summary>
        /// <param name="folder">Répertoire à zipper</param>
        /// <param name="zipFilename">Nom du fichier zip</param>
        public void ZipFolder(string folder, string zipFilename)
        {
            try
            {
                if (!folder.EndsWith("\\"))
                {
                    folder += "\\";
                }

                var zipFolder = Path.GetDirectoryName(zipFilename);
                if (Directory.Exists(zipFolder)) {
                    Directory.CreateDirectory(zipFolder);
                }

                // Depending on the directory this could be very large and would require more attention
                // in a commercial package.
                //string[] filenames = Directory.GetFiles(folder);

                DirectoryInfo di = new DirectoryInfo(folder);
                FileInfo[] files = di.GetFiles("*.*", SearchOption.AllDirectories);

                // 'using' statements guarantee the stream is closed properly which is a big source
                // of problems otherwise.  Its exception safe as well which is great.
                using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilename)))
                {

                    s.SetLevel(9); // 0 - store only to 9 - means best compression

                    byte[] buffer = new byte[4096];

                    foreach (FileInfo file in files)
                    {

                        // Using GetFileName makes the result compatible with XP
                        // as the resulting path is not absolute.
                        var vpSourceFile = file.FullName.Replace(folder, string.Empty);
                        vpSourceFile = vpSourceFile.Replace("\\", "/");
                        ZipEntry entry = new ZipEntry(vpSourceFile);

                        // Setup the entry data as required.

                        // Crc and size are handled by the library for seakable streams
                        // so no need to do them here.

                        // Could also use the last write time or similar for the file.
                        entry.DateTime = DateTime.Now;
                        s.PutNextEntry(entry);

                        using (FileStream fs = File.OpenRead(file.FullName))
                        {

                            // Using a fixed size buffer here makes no noticeable difference for output
                            // but keeps a lid on memory usage.
                            int sourceBytes;
                            do
                            {
                                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                                s.Write(buffer, 0, sourceBytes);
                            } while (sourceBytes > 0);
                        }
                    }

                    // Finish/Close arent needed strictly as the using statement does this automatically

                    // Finish is important to ensure trailing information for a Zip file is appended.  Without this
                    // the created file would be invalid.
                    s.Finish();

                    // Close is important to wrap things up and unlock the file.
                    s.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception during processing {0}", ex);

                // No need to rethrow the exception as for our purposes its handled.
            }
        }

        #endregion

    }
}
